{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Draw Countries Polygons From a File GeoDatabase"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Read a GDB table as Spark DataFrame and create `Countries` temp table."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "spark.read \\\n",
    "    .format('com.esri.gdb') \\\n",
    "    .options(path='data/World.gdb', name='Countries') \\\n",
    "    .load() \\\n",
    "    .registerTempTable('Countries')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Read the `name` and `shape` and convert it to a Pandas DataFrame."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sql(\"describe Countries\").show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "pdf = sql(\"select ADMIN_NAME,Shape.parts as parts, Shape.coords as coords from Countries\").toPandas()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Function to convert `parts` array\\[Int\\] and `coords` array\\[Double\\] to a `Polygon` instance."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def to_geom(parts,coords):\n",
    "    rings = []\n",
    "    i = 0\n",
    "    j = 2\n",
    "    for num_points in parts:\n",
    "        ring = []\n",
    "        n = 0\n",
    "        while n < num_points:\n",
    "            ring.append(coords[i:j])\n",
    "            i += 2\n",
    "            j += 2\n",
    "            n += 1\n",
    "        rings.append(ring)\n",
    "    return Polygon({\"spatialReference\" : {\"wkid\" : 4326}, \"rings\": rings})"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Convert `parts` and `coords` to a `Polygon` for each row and create the required `SHAPE` column."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "pdf['SHAPE'] = pdf.apply(lambda row: to_geom(row.parts,row.coords), axis=1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Drop the `parts` and `coords` columns, and create a `SpatialDataFrame`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sdf = SpatialDataFrame(pdf.drop(['parts','coords'], axis=1))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Create a map."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "gis = GIS()\n",
    "m = gis.map()\n",
    "m.basemap = 'dark-gray'\n",
    "m"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Plot the Spatial DF on the map"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sdf.plot(kind='map', map_widget=m, alpha=0.4)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
